package be.ipl.finito.usecasesimpl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Singleton;
import javax.ejb.Startup;

import be.ipl.finito.dao.CaseDao;
import be.ipl.finito.dao.GrilleDao;
import be.ipl.finito.dao.JetonDao;
import be.ipl.finito.dao.JoueurDao;
import be.ipl.finito.dao.PartieDao;
import be.ipl.finito.domaine.Case;
import be.ipl.finito.domaine.Grille;
import be.ipl.finito.domaine.Jeton;
import be.ipl.finito.domaine.Joueur;
import be.ipl.finito.domaine.Partie;
import be.ipl.finito.domaine.Partie.Etat;
import be.ipl.finito.usecases.GestionPartie;

@Singleton
@Startup
public class GestionPartieImpl implements GestionPartie {

	@EJB
	JoueurDao joueurDao;
	@EJB
	PartieDao partieDao;
	@EJB
	JetonDao jetonDao;
	@EJB
	CaseDao caseDao;

	@EJB
	GrilleDao grilleDao;

	@Override
	public Partie creerPartie(String loginJoueur) {
		Joueur j = joueurDao.rechercher(loginJoueur);
		if (j == null)
			return null;

		Partie p = new Partie(j);
		InitialiserJeton(p);
		p = partieDao.enregistrer(p);
		p = partieDao.chargerTout(p.getIdPartie());
		return p;

	}

	private void InitialiserJeton(Partie partie) {
		List<Jeton> temp = new ArrayList<Jeton>();
		temp.addAll(jetonDao.lister());
		Collections.shuffle(temp);
		for (int i = 1; i <= 12; i++) {
			partie.getJeton().put(i, temp.get(i - 1));
		}
	}

	@Override
	public Partie commencerPartie(int idPartie) {
		Partie p = partieDao.rechercher(idPartie);
		if (p == null)
			return null;

		p.commancerPartie();
		p = partieDao.chargerTout(idPartie);
		return p;
	}

	public Partie abandonnerPartie(int idPartie, String loginJoueur) {
		Partie p = partieDao.rechercher(idPartie);
		Joueur j = joueurDao.rechercher(loginJoueur);
		if (p == null || j == null)
			return null;
		p.abandoner(j);
		p = partieDao.chargerTout(idPartie);
		return p;
	}
	
	
	@Override
	public Partie rejoindreLaPartie(int idPartie, String login) {
		Partie p = partieDao.rechercher(idPartie);
		if (p == null)
			return null;
		Joueur joueur = joueurDao.rechercher(login);
		if (joueur == null)
			return null;
		p.rejoindrePartie(joueur);
		p = partieDao.chargerTout(idPartie);
		return p;
	}
	
	public Partie reprendrePartie(int idPartie, String login){
		Partie p = partieDao.rechercher(idPartie);
		if (p == null)
			return null;
		Joueur joueur = joueurDao.rechercher(login);
		if (joueur == null)
			return null;
		
		if(p.reprendrePartie(joueur)){
			return null;
		}
		p = partieDao.chargerTout(idPartie);
		return p;
	}

	public boolean partieEstAnnuler(int idPartie) {
		Partie p = partieDao.rechercher(idPartie);
		if (p == null)
			return false;

		if (p.getJoueurs().size() >= Partie.MIN_JOUEURS)
			return true;
		return false;
	}

	// pour Dashboard
	@Override
	public List<Partie> getPartiesEnAttenteDeJoueur() {
		List<Partie> parties = partieDao.listerPartieEnAttenteDeJoueur();
		List<Partie> partiesChargees = new ArrayList<Partie>();
		for (Partie partie : parties) {
			partiesChargees.add(partieDao.chargerTout(partie.getIdPartie()));
		}
		return partiesChargees;
	}

	// pour Dashboard
	public List<Partie> getPartiesAbandonneesDunJoueur(String login) {
		Joueur j = joueurDao.rechercher(login);
		if (j == null)
			return null;
		return partieDao.listerPartieAbandonnerDunJoueur(j);
	}

	@Override
	public List<Joueur> getJoueursDunePartie(int idPartie) {
		Partie p = partieDao.rechercher(idPartie);
		if (p == null)
			return null;

		return partieDao.listerJoueurs(idPartie);

	}

	public List<Grille> getGrillesTrieesPartieFini(int idPartie) {
		// le 1er est le gagnant
		Partie p = partieDao.rechercher(idPartie);
		if (p == null)
			return null;
		partieDao.chargerTout(idPartie);
		return p.getClassement();
	}

	public Jeton tirageJeton(int idPartie) {
		Partie p = partieDao.rechercher(idPartie);
		if (p == null)
			return null;

		Jeton j = p.tirage();
		j = jetonDao.rechercher(""+j.getNumero());
		return j;
	}

	public int lancerDe(int idPartie) {
		Partie p = partieDao.rechercher(idPartie);
		if (p == null)
			return -1;

		return p.lancerDe();

	}

	// pour Dashboard
	public int getStatDefaiteJoueur(String login) {
		Joueur j = joueurDao.rechercher(login);
		if (j == null)
			return -1;
		return partieDao.getStatDefaiteJoueur(j);

	}

	// pour Dashboard
	public int getStatVictoireJoueur(String login) {
		Joueur j = joueurDao.rechercher(login);
		if (j == null)
			return -1;
		return partieDao.getStatVictoireJoueur(j);
	}

	public int getPointsTotalJoueur(String login) {
		Joueur j = joueurDao.rechercher(login);
		if(j == null){
			return 0;
		}
		return partieDao.getPointsJoueur(j);
	}

	public boolean placerJeton(int idGrille, int numeroCase,
			int numJeton) {

		// on verifie si la grille est presente dans la liste des grilles
		Grille grille = grilleDao.rechercher(idGrille);
		if (grille == null)
			return false;

		// on cherche le jeton et on verifie s'il il existe.
		Jeton j = jetonDao.rechercher(numJeton);
		if (j == null)
			return false;
		Case c = new Case(j, numeroCase);
		c = caseDao.enregistrer(c);
		return grille.placerJeton(c);
	}

	public Partie getPartie(int idPartie) {
		Partie p = partieDao.rechercher(idPartie);
		if (p == null)
			return null;
		p = partieDao.chargerTout(idPartie);
		return p;
	}

	@Override
	public boolean annulerPartie(int idPartie) {
		Partie p = partieDao.rechercher(idPartie);
		if (p == null)
			return false;
		if (p.annulerPartie()) {
			partieDao.supprimer(p.getIdPartie());
			return true;
		}
		return false;
	}

	@Override
	public Grille getGrille(int idPartie, String loginJoueur) {
		Partie p = partieDao.rechercher(idPartie);
		if (p == null)
			return null;
		
		p = partieDao.chargerTout(idPartie);
		
		Joueur j = joueurDao.rechercher(loginJoueur);
		if (j == null)
			return null;

		for (Grille g : p.getGrilles()) {
			if (j.getLogin().equals(g.getJoueur().getLogin())){
				g = grilleDao.chargerGrille(g.getId());
				return g;
			}
		}
		return null;
	}

	@Override
	public List<Jeton> getReserveJeton(int idPartie, String loginJoueur) {
		Grille g = getGrille(idPartie, loginJoueur);
		if (g == null)
			return null;
		
		Partie p = partieDao.rechercher(idPartie);
		p = partieDao.chargerTout(idPartie);
		p.tirage();
		
		return g.getJetons();
	}

	@Override
	public boolean isPartieFini(int idPartie) {
		Partie p = partieDao.rechercher(idPartie);
		if (p == null)
			return false;
		return p.getEtat() == Etat.FINIE;

	}

	@Override
	public List<Jeton> getReserveJetonPremierTirage(int idPartie) {
		Partie p = partieDao.rechercher(idPartie);
		p = partieDao.chargerTout(idPartie);
		List<Jeton> jetons = new ArrayList<Jeton>();
		jetons.add(p.tirage());
		jetons.add(p.tirage());
		jetons.add(p.tirage());
		
		return jetons;
	}

	@Override
	public boolean indiceCourantMax(int idPartie) {
		Partie p = partieDao.rechercher(idPartie);
		p = partieDao.chargerTout(idPartie);
		return p.getIndiceCourant() == 13;
	}

	@Override
	public Partie finirPartie(int idPartie) {
		Partie p = partieDao.rechercher(idPartie);
		p.finirPartie();
		return p;
	}
}